﻿using KWT.DRG_DIP.API.Infrastructure;
using KWT.DRG_DIP.DO.Group;
using KWT.DRG_DIP.DO.Group.DIPGroup;
using KWT.DRG_DIP.DO.System;
using KWT.DRG_DIP.DTO.Group;
using KWT.DRG_DIP.ISvc;
using KWT.DRG_DIP.PO.Basic;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace KWT.DRG_DIP.API.Controllers.Grouper
{
    /// <summary>
    /// DIP分组策略字典
    /// </summary>
    [AllowAnonymous]
    [ApiExplorerSettings(GroupName = "grouper")]
    public class DIPController : GrouperControllerBase
    {


        public IPolicyEnumSvc policyEnumSvc { get; set; }
        public IDipGrouperSvc dipGrouperSvc { get; set; }

        /// <summary>
        /// 手术信息库
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(Output<List<OperInfo>>), 200)]
        public OutputResult OperInfo()
        {
            string? tenantID = HttpContext.Request.Headers["TenantID"];
            if (string.IsNullOrEmpty(tenantID))
            {
                return Fail("缺少租户ID");
            }
            var list = policyEnumSvc.GetOperInfo(tenantID);
            return Output(true, "", "", list);
        }

        /// <summary>
        /// DIP分组标杆
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(Output<List<Sys_DIP_Para>>), 200)]
        public OutputResult List()
        {
            string? tenantID = HttpContext.Request.Headers["TenantID"];
            if (string.IsNullOrEmpty(tenantID))
            {
                return Fail("缺少租户ID");
            }
            if (RedisHelper.HExists("PolicyEnum-" + tenantID, "DIPPara"))
            {
                RedisHelper.HGet<List<Sys_DIP_Para>>("PolicyEnum-" + tenantID, "DIPPara");
            }
            var list = ef.Set<Sys_DIP_Para>().ToList();
            RedisHelper.HSet("PolicyEnum-" + tenantID, "DIPPara", list);
            return Output(true, "", "", list);
        }


        #region  ICD10 诊断列表（模糊查询）
        /// <summary>
        /// ICD10 诊断列表（模糊查询）
        /// </summary>
        /// <param name="input">输入的文本</param>
        /// <param name="count">取前count 条</param>
        /// <returns></returns>
        [HttpGet]
        [AllowAnonymous]
        public OutputResult TopDiagnose([FromQuery] string input, int count = 100)
        {

            //select a.Code2,a.Name2,b.Code1 from sys_policyenum a left join sys_policyenum b on b.`Group`= '不作为诊断' and a.Code2 = b.Code1
            //where a.`Group`= '主诊断' and a.Code2 like '%A%'
            //limit 10
            var result = ef.Set<Sys_PolicyEnum>()
                        // 左表条件过滤
                        .Where(a => a.Group == "主诊断" &&
                            (EF.Functions.Like(a.PinYin2, $"%{input}%") ||
                                EF.Functions.Like(a.Name2, $"%{input}%") ||
                                EF.Functions.Like(a.Code2, $"%{input}%")))
                        // 左连接逻辑
                        .GroupJoin(
                            ef.Set<Sys_PolicyEnum>().Where(b => b.Group == "不作为诊断"),
                            a => a.Code2,
                            b => b.Code1,
                            (a, bGroup) => new { a, bGroup }
                        )
                        // 展平连接结果
                        .SelectMany(
                            x => x.bGroup.DefaultIfEmpty(),
                            (a, b) => new
                            {
                                medicalInsuranceCode = a.a.Code2,
                                medicalInsuranceName = a.a.Name2,
                                IsNotDiagnose = b == null ? 0 : 1
                            }
                        )
                        // 分页控制
                        .Take(count)
                        .ToList();
            return Output(result != null, "", "", result);
        }
        #endregion

        #region  ICD9 手术列表（模糊查询）
        /// <summary>
        /// ICD9 手术列表（模糊查询）
        /// </summary>
        /// <param name="input">输入的文本</param>
        /// <param name="count">取前count 条</param>
        /// <returns></returns>
        [HttpGet]
        [AllowAnonymous]
        public OutputResult TopOperation([FromQuery] string input, int count = 100)
        {

            //select a.Code2,a.Name2,b.Code1 from sys_policyenum a left join sys_policyenum b on b.`Group`= '不作为诊断' and a.Code2 = b.Code1
            //where a.`Group`= '主诊断' and a.Code2 like '%A%'
            //limit 10
            var result = ef.Set<Sys_PolicyEnum>()
                        // 左表条件过滤
                        .Where(a => a.Group == "手术信息库" &&
                            (EF.Functions.Like(a.PinYin2, $"%{input}%") ||
                                EF.Functions.Like(a.Name2, $"%{input}%") ||
                                EF.Functions.Like(a.Code2, $"%{input}%")))
                        // 左连接逻辑
                        .GroupJoin(
                            ef.Set<Sys_PolicyEnum>().Where(b => b.Group == "不作为手术"),
                            a => a.Code2,
                            b => b.Code1,
                            (a, bGroup) => new { a, bGroup }
                        )
                        // 展平连接结果
                        .SelectMany(
                            x => x.bGroup.DefaultIfEmpty(),
                            (a, b) => new
                            {
                                medicalInsuranceCode = a.a.Code2,
                                medicalInsuranceName = a.a.Name2,
                                IsNotOperation = b == null ? 0 : 1
                            }
                        )
                        // 分页控制
                        .Take(count)
                        .ToList();
            return Output(result != null, "", "", result);
        }
        #endregion

        #region 转码
        /// <summary>
        /// 将诊断医院编码转换医保编码
        /// </summary>
        /// <param name="diagnoses"></param>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        public OutputResult Diagnose_ICD10Transcoding([FromBody] List<Diagnose> diagnoses)
        {
            var data = ef.Set<Sys_PolicyEnum>().Where(a => a.Group == "主诊断" && diagnoses.Select(x => x.medicalInsuranceCode).Contains(a.Code1)).Select(temp => new
            {
                medicalInsuranceCode = temp.Code2,
                medicalInsuranceName = temp.Name2,
                diagnosisCode = temp.Code1,
                diagnosisName = temp.Name1
            }).ToList();
            return Output(true, "", "", data);
        }

        /// <summary>
        /// 将手术医院编码转换医保编码
        /// </summary>
        /// <param name="operations"></param>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        public OutputResult Operation_ICD9Transcoding([FromBody] List<Operation> operations)
        {
            var data = ef.Set<Sys_PolicyEnum>().Where(a => a.Group == "手术信息库" && operations.Select(x => x.medicalInsuranceCode).Contains(a.Code1)).Select(temp => new
            {
                medicalInsuranceCode = temp.Code2,
                medicalInsuranceName = temp.Name2,
                operationCode = temp.Code1,
                operationName = temp.Name1
            }).ToList();

            return Output(true, "", "", data);
        }


        #endregion

        #region  根据主要诊断获得推荐病种
        /// <summary>
        /// 根据主要诊断获得推荐病种
        /// </summary>
        /// <param name="diagnoseCode">诊断编码</param>
        /// <returns></returns>
        [HttpGet]
        [AllowAnonymous]
        [ProducesResponseType(typeof(Output<Sys_DIP_Para>), 200)]
        public OutputResult SuggestGroupDiagnose([FromQuery] string diagnoseCode)
        {
            string? tenantID = HttpContext.Request.Headers["TenantID"];
            if (string.IsNullOrEmpty(tenantID))
            {
                return Fail("缺少租户ID");
            }

            if (diagnoseCode == null || diagnoseCode.Length < 5)
            {
                return Fail("主要诊断编码错误");
            }
            string Suborder = diagnoseCode.Substring(0, 5);
            string Category = diagnoseCode.Substring(0, 3);
            var result = ef.Set<Sys_DIP_Para>().Where(x => (x.Diag_Code == Suborder && x.Disease_Type == "核心病种") || (x.Diag_Code == Category && x.Disease_Type == "综合病种")).OrderByDescending(x => x.Disease_Type).ThenByDescending(x => x.Score).ToList();
            return Output(true, "", "", result);
        }
        #endregion

        #region 根据主要手术获得推荐病种
        /// <summary>
        /// 根据主要手术获得推荐病种
        /// </summary>
        /// <param name="operationCode">手术编码</param>
        /// <returns></returns>
        [HttpGet]
        [AllowAnonymous]
        [ProducesResponseType(typeof(Output<Sys_DIP_Para>), 200)]
        public OutputResult SuggestGroupOperation([FromQuery] string operationCode)
        {
            string? tenantID = HttpContext.Request.Headers["TenantID"];
            if (string.IsNullOrEmpty(tenantID))
            {
                return Fail("缺少租户ID");
            }
            var results = ef.Set<Sys_DIP_Para>().Where(x => x.Oper_Code == operationCode).OrderBy(x => x.Diag_Code).ThenByDescending(x => x.Disease_Type).ThenByDescending(x => x.Score).ToList();

            if (results.Count > 10)
            {
                return Output(true, "", "", results);
            }
            else
            {
                List<Sys_DIP_Para> lstReturn = new List<Sys_DIP_Para>();
                foreach (var item in results)
                {
                    var result = ef.Set<Sys_DIP_Para>().Where(x => x.Diag_Code == item.Diag_Code).OrderBy(x => x.Oper_Code).ThenByDescending(x => x.Disease_Type).ThenByDescending(x => x.Score).ToList();
                    lstReturn.AddRange(result);
                }
                return Output(true, "", "", lstReturn);
            }


        }
        #endregion

        #region DIP分组器,返回病种对应的分组信息
        /// <summary>
        /// DIP分组器,返回病种对应的分组信息
        /// </summary>
        /// <param name="input">DIP分组器入参</param>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        public OutputResult DIPGroupInfo([FromBody] InGroupPara input)
        {
            string? tenantID = HttpContext.Request.Headers["TenantID"];
            if (string.IsNullOrEmpty(tenantID))
            {
                return Fail("缺少租户ID");
            }
            var result = dipGrouperSvc.GroupExecue(input, tenantID);
            return Output(true, "", "", result);
        }
        #endregion

        #region DIP分组器,返回病种对应的标杆信息
        /// <summary>
        /// DIP分组器,返回病种对应的标杆信息
        /// </summary>
        /// <param name="input">DIP分组器入参</param>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        [ProducesResponseType(typeof(Output<OutGroupBenchmark>), 200)]
        public OutputResult DIPGroup([FromBody] InGroupPara input)
        {
            string? tenantID = HttpContext.Request.Headers["TenantID"];
            if (string.IsNullOrEmpty(tenantID))
            {
                return Fail("缺少租户ID");
            }
            //获得DIP分组结果
            var result = dipGrouperSvc.GroupExecue(input, tenantID);
            if (!result.Success)
            {
                return Output(false, "", "", result.msg);
            }
            Sys_DIP_Para? sys_DIP_Para = ef.Set<Sys_DIP_Para>().FirstOrDefault(x => x.Disease_Code == result.strResult);
            var result1 = new object();
            if (result.dIP_Assist != null)
            {
                //查找对应的辅助目录关系
                var standardAssist = ef.Set<Sys_PolicyEnum>().FirstOrDefault(a => a.Group == "辅助目录关系"
                && a.Name3 == result.dIP_Assist.Type && a.Code2 == result.dIP_Assist.Code);
                if (standardAssist == null)
                {
                    return Fail($"缺辅助目录关系未能对应上{result.dIP_Assist.Type},{result.dIP_Assist.Code}");
                }
                result1 = new OutGroupBenchmark
                {
                    Disease_Code = sys_DIP_Para.Disease_Code,
                    Disease_Name = sys_DIP_Para.Disease_Name,
                    Disease_Type = sys_DIP_Para.Disease_Type,
                    Diag_Code = sys_DIP_Para.Diag_Code,
                    Diag_Name = sys_DIP_Para.Diag_Name,
                    Oper_Code = sys_DIP_Para.Oper_Code,
                    Oper_Name = sys_DIP_Para.Oper_Name,
                    Other_Code = sys_DIP_Para.Other_Code,
                    Other_Name = sys_DIP_Para.Other_Name,
                    SpecialFlag = sys_DIP_Para.SpecialFlag,
                    Score = sys_DIP_Para.Score,
                    AssistType = result.dIP_Assist.Type,
                    AssistCode = standardAssist.Code1,
                    AssistName = standardAssist.Name1,
                    AssistRatio = result.dIP_Assist.Ratio,
                    ZGDZ = result.dIP_Assist.ZGDZ,
                    JMDZ = result.dIP_Assist.JMDZ,
                    ZGFFBZ = result.dIP_Assist.ZGFFBZ,
                    JMFFBZ = result.dIP_Assist.JMFFBZ,
                    LJFY = result.dIP_Assist.LJFY,
                    HighMag = result.dIP_Assist.HighMag,
                    LowMag = result.dIP_Assist.LowMag,
                    ZYTSBGZ = result.dIP_Assist.ZYTSBGZ,
                };
            }
            else
            {
                result1 = new OutGroupBenchmark
                {
                    Disease_Code = sys_DIP_Para.Disease_Code,
                    Disease_Name = sys_DIP_Para.Disease_Name,
                    Disease_Type = sys_DIP_Para.Disease_Type,
                    Diag_Code = sys_DIP_Para.Diag_Code,
                    Diag_Name = sys_DIP_Para.Diag_Name,
                    Oper_Code = sys_DIP_Para.Oper_Code,
                    Oper_Name = sys_DIP_Para.Oper_Name,
                    Other_Code = sys_DIP_Para.Other_Code,
                    Other_Name = sys_DIP_Para.Other_Name,
                    Score = sys_DIP_Para.Score,
                    SpecialFlag = sys_DIP_Para.SpecialFlag,
                    AssistType = "",
                    AssistCode = "",
                    AssistName = "",
                    AssistRatio = 1,
                    ZGDZ = sys_DIP_Para.ZGDZ,
                    JMDZ = sys_DIP_Para.JMDZ,
                    ZGFFBZ = sys_DIP_Para.ZGFFBZ,
                    JMFFBZ = sys_DIP_Para.JMFFBZ,
                    LJFY = sys_DIP_Para.LJFY,
                    HighMag = sys_DIP_Para.HighMag,
                    LowMag = sys_DIP_Para.LowMag,
                    ZYTSBGZ = sys_DIP_Para.ZYTSBGZ,
                };
            }

            return Output(true, "", "", result1);
        }
        #endregion
    }
}
